﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using RFIDStockManagement.BLL;
using RFIDStockManagement.Common.Public.Enums;
using Impinj.OctaneSdk;
using System.Threading;
using RFIDStockManagement.Common.Public;

namespace RFIDStockManagement.Client
{
    public partial class WriteTag : XtraUserControl
    {
        private SpeedwayReader m_Reader = null;

        public WriteTag()
        {
            InitializeComponent();
            m_Reader = new SpeedwayReader();
            m_Reader.TagsReported += new EventHandler<TagsReportedEventArgs>(OnTagsReported);
        }
        private Dictionary<string, TagStatusData> m_dctTagList = null;
        private void OnTagsReported(object sender, TagsReportedEventArgs args)
        {
            if (m_dctTagList == null) return;

            TagStatusData data = null;
            foreach (var item in args.TagReport.Tags)
            {
                if (m_dctTagList.TryGetValue(item.Epc, out data))
                {
                    data.Active = true;
                    data.ReadTime = DateTime.Now;
                }
                else
                {
                    m_dctTagList[item.Epc] = TagStatusData.CreateOne();
                }
                //Console.WriteLine(string.Format("Reader:{0}", item.Epc));
            }
        }

        private void WriteTag_Load(object sender, EventArgs e)
        {
            try
            {
                BindItemList();
            }
            catch (Exception ex)
            {
                AlertForm.ShowError(ex.Message);
            }
        }


        private Dictionary<int, DataRow> m_ItemIndex = new Dictionary<int, DataRow>();
        private void BindItemList()
        {
            DataTable dtItemList = BasicInfoManager.GetList(null, EnumBasicInfo.Item);
            if (dtItemList != null)
            {
                cbbItem.Properties.BeginUpdate();
                foreach (DataRow row in dtItemList.Rows)
                {
                    int index = cbbItem.Properties.Items.Add(string.Format("{0}({1})", row["FName"], row["FNumber"]));
                    m_ItemIndex[index] = row;// long.Parse(row["FID"].ToString());
                }
                cbbItem.Properties.EndUpdate();
            }
        }
        private Dictionary<int, long> m_MeasureIndex = null;
        private void cbbItem_SelectedIndexChanged(object sender, EventArgs e)
        {
            DataRow itemRow = null;
            m_MeasureIndex = new Dictionary<int, long>();
            cbbUnit.Properties.Items.Clear();
            cbbUnit.SelectedIndex = -1;
            if (m_ItemIndex.TryGetValue(cbbItem.SelectedIndex, out itemRow))
            {
                Dictionary<string, object> filter = new Dictionary<string, object>();
                filter.Add("FMeasureGroupID", itemRow["FMeasureGroupID"]);
                DataTable dtMeasure = BasicInfoManager.GetList(filter, EnumBasicInfo.Measure);
                if (dtMeasure != null)
                {
                    cbbUnit.Properties.BeginUpdate();
                    foreach (DataRow row in dtMeasure.Rows)
                    {
                        int index = cbbUnit.Properties.Items.Add(string.Format("{0}({1})", row["FName"], row["FNumber"]));
                        long id = long.Parse(row["FID"].ToString());
                        m_MeasureIndex[index] = id;
                    }
                    cbbUnit.Properties.EndUpdate();
                }
            }
        }
        private bool m_IsConnected = false;
        private void btnStart_Click(object sender, EventArgs e)
        {
            string readerName = string.Empty;
            try
            {
                #region 检查
                readerName = txtIP.Text.Trim();
                if (string.IsNullOrEmpty(readerName))
                {
                    AlertForm.ShowMessage("请speedway的连接地址");
                    return;
                }
                #endregion

                btnStart.Enabled = false;
                btnWriteTag.Enabled = true;
                if (m_IsConnected == false)
                {
                    m_Reader.Connect(readerName);
                    m_IsConnected = true;
                    m_Reader.ClearSettings();
                    Settings settings = m_Reader.QueryFactorySettings();
                    settings.Report.IncludeAntennaPortNumber = true;
                    settings.Report.Mode = ReportMode.Individual;
                    m_Reader.ApplySettings(settings);
                }

                StartRead();
            }
            catch (Exception ex)
            {
                AlertForm.ShowError(ex.Message);
                btnStart.Enabled = true;
                cbbItem.Enabled = true;
                cbbUnit.Enabled = true;
                btnWriteTag.Enabled = false;
            }
        }
        private void btnWriteTag_Click(object sender, EventArgs e)
        {
            try
            {
                if (cbbItem.SelectedIndex < 0)
                {
                    AlertForm.ShowMessage("请选择一个物料");
                    return;
                }
                if (cbbUnit.SelectedIndex < 0)
                {
                    AlertForm.ShowMessage("请选择一个单位");
                    return;
                }
                cbbItem.Enabled = false;
                cbbUnit.Enabled = false;
                btnWriteTag.Enabled = false;

                StopRead(false);
                List<string> lstTag = new List<string>();
                foreach (KeyValuePair<string, TagStatusData> item in m_dctTagList)
                {
                    if (item.Value.Active)
                    {
                        lstTag.Add(item.Key);
                    }
                }
                if (lstTag.Count > 0)
                {
                    int successCount = 0;
                    int failCount = 0;
                    long itemId = Convert.ToInt64(m_ItemIndex[cbbItem.SelectedIndex]["FID"]);
                    long unitId = m_MeasureIndex[cbbUnit.SelectedIndex];
                    long rfidEnd = MakeItemRfid.CreateNewItemRfid(itemId, unitId, lstTag.Count);

                    //m_Reader.ApplyFactorySettings();
                    ProgramEpcParams epcParams = new ProgramEpcParams();
                    epcParams.TimeoutInMs = 5000;
                    epcParams.LockType = LockType.Locked;
                    epcParams.RetryCount = 5;
                    epcParams.AntennaPortNumber = 1;
                    //epcParams.AccessPassword = null;
                    foreach (string targetTag in lstTag)
                    {
                        epcParams.TargetTag = targetTag;
                        epcParams.NewEpc = SpeedwayPublicFunction.ConvertRfid(itemId, unitId, rfidEnd);
                        ProgramEpcResult result = m_Reader.ProgramEpc(epcParams);
                        if (result.WriteResult.Result == AccessResult.Success)
                        {
                            successCount++;
                        }
                        else
                        {
                            failCount++;
                        }
                        rfidEnd--;
                        Thread.Sleep(50);
                    }
                    AlertForm.ShowMessage(string.Format("写入成功{0}个，失败{1}个", successCount, failCount));
                }
                else
                {
                    AlertForm.ShowMessage("没有可写的标签");
                }

                StartRead();
                btnStart.Enabled = false;
                btnWriteTag.Enabled = true;
                cbbItem.Enabled = true;
                cbbUnit.Enabled = true;
            }
            catch (Exception ex)
            {
                StartRead();
                AlertForm.ShowError(ex.Message);
                btnWriteTag.Enabled = true;
                cbbItem.Enabled = true;
                cbbUnit.Enabled = true;
            }
        }

        private Thread m_UpdateThread = null;
        public void StartRead()
        {
            try
            {
                m_dctTagList = new Dictionary<string, TagStatusData>();
                if (!m_Reader.QueryStatus().IsSingulating)
                {
                    m_Reader.Start();
                }
                m_UpdateThread = new Thread(new ThreadStart(UpdateTagData));
                m_UpdateThread.Start();
            }
            catch (Exception ex)
            { }
        }
        private void UpdateTagData()
        {
            while (true)
            {
                try
                {
                    if (m_dctTagList != null)
                    {
                        DateTime dtNow = DateTime.Now;
                        int iCount = 0;
                        foreach (TagStatusData data in m_dctTagList.Values)
                        {
                            if ((dtNow - data.ReadTime).TotalMilliseconds > 2000)
                            {
                                data.Active = false;
                            }
                            else
                            {
                                iCount++;
                            }
                        }
                        UpateUIDelegate delegateMothod = new UpateUIDelegate(UpateUIHandler);
                        this.Invoke(delegateMothod, iCount);
                    }
                    Thread.Sleep(1000);
                }
                catch (Exception ex)
                { }
            }
        }
        private delegate void UpateUIDelegate(int iCount);
        private void UpateUIHandler(int iCount)
        {
            txtCount.Text = iCount.ToString();
        }

        public void StopRead(bool disConnect)
        {
            try
            {
                if (m_Reader.QueryStatus().IsSingulating)
                {
                    m_Reader.Stop();
                }
                if (disConnect)
                {
                    m_Reader.Disconnect();
                }
                if (m_UpdateThread != null)
                {
                    m_UpdateThread.Abort();
                }
            }
            catch (Exception ex)
            { }
        }

        public class TagStatusData
        {
            public static TagStatusData CreateOne()
            {
                return new TagStatusData() 
                {
                    ReadTime = DateTime.Now,
                    Active = true,
                };
            }
            public DateTime ReadTime { get; set; }
            public bool Active { get; set; }
        }
    }

    
}
